package sound;

/**
 * @author Yogeswar Vijayakumar
 * class: AudioPlayer
 * Purpose: This class will playback an audio file. Tested only with a .au file with the following format
 * 	PCM_SIGNED 8000.0 Hz, 16 bit, mono, 2 bytes/frame, big-endian
 * Input File Format : PCM-signed *.au file
 * Input File Type : File, filepath
 * References :  
 * 1. Richard G. Baldwin - Java Sound Tutorial - http://www.developer.com/java/other/article.php/1565671/Java-Sound-An-Introduction.htm
 * 2. Richard G. Baldwin - Java Sound Playback Tutorial - http://www.developer.com/java/other/article.php/1572251
 * 																/Java-Sound-Getting-Started-Part-1-Playback.htm
 * 
 */


import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

public class AudioPlayer {

	AudioFormat audioFormat;
	AudioInputStream audioInputStream;
	SourceDataLine sourceDataLine;
	boolean playback = true;
	File recorded;
	
	public AudioPlayer()
	{
		
	}
	
	public AudioPlayer(String filepath)
	{
		this.recorded = new File(filepath);
	}
	
	//store the recorded file
	public AudioPlayer(File record)
	{
		this.recorded = record;
	}
	
	public void setRecorded(File record)
	{
		this.recorded = record;
	}
	
	public void setRecorded(String filepath)
	{
		this.recorded = new File(filepath);
	}
	
	public File getRecorded()
	{
		File temp = this.recorded;
		return temp;
	}
	
	//get the path of file to be recorded
	public String getRecordedFilePath()
	{
		return this.recorded.getAbsolutePath();
	}
	
	public boolean getPlayerStatus()
	{
		return this.playback;
	}
	
	public void stopPlayback()
	{
		this.playback = false;
	}
	
	//begin playing the audio file
	public void startPlayback()
	{
		try 
		{
			this.audioInputStream = AudioSystem.getAudioInputStream(this.recorded);
		}
		catch (UnsupportedAudioFileException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//Gets the format of the audio file
		this.audioFormat = this.audioInputStream.getFormat();
		System.out.println(audioFormat);
		DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);

		try 
		{
			this.sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo);
		}
		catch (LineUnavailableException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try
		{
			new PlayThread().start();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		    System.exit(0);
		}	
		
	}
	
	
	
	
	class PlayThread extends Thread
	{
		byte buffer[] = new byte[10000];
		
		public void run()
		{
			try {
				sourceDataLine.open(audioFormat);
			} catch (LineUnavailableException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			sourceDataLine.start();
			
			int counter;
			
			try {
				while((counter = audioInputStream.read(buffer,0,buffer.length)) != -1 && playback == true)
				{
					System.out.println(buffer);
					if(counter > 0)
					{
						sourceDataLine.write(buffer,0,counter);
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			sourceDataLine.drain();
			sourceDataLine.close();
			System.out.println("Playback Stopped");
			playback = true;
		}
		
	}
	
	public boolean getStatus()
	{
		return this.playback;
	}
	
	public static void main(String args[]) throws IOException
	{
		System.out.println("Testing AudioPlayer");
		String path = "recorded.au";
		AudioPlayer testPlayer = new AudioPlayer(path);
		System.out.println("press Enter to start playing");
		System.in.read();
		
		testPlayer.startPlayback();

		System.out.println("press Enter to stop playing");
		System.in.read();
		
		//testPlayer.stopPlayback();
	}
	
}
